package cn.javacart.jopencart.library;

import java.io.File;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import php.runtime.Memory;
import php.runtime.env.CompileScope;
import php.runtime.env.Environment;
import php.runtime.lang.ForeachIterator;
import php.runtime.memory.ReferenceMemory;
import php.runtime.memory.support.MemoryUtils;
import php.runtime.reflection.ModuleEntity;
import cn.javacart.jfinal.php.render.PhpEnvKit;
import cn.javacart.jfinal.php.render.PhpEnvironment;
import cn.javacart.jfinal.php.render.PhpRenderException;

import com.jfinal.kit.LogKit;
import com.jfinal.render.RenderException;

/**
 * 
 * @author farmer
 *
 */
public class LanguageService {
	
	//
	private static LanguageService languageService = null;
	//当前线程设置的语言文件
	private static ThreadLocal<String> currentLoad = new ThreadLocal<String>();
	//全部语言Map
	private Map<String, Map<String, String>> allLangMap = new HashMap<String, Map<String,String>>();
	//系统默认的语言
	private Map<String, String> defaultLangMap = null;
	//Session默认语言Map
	private Map<String, Map<String, String>> sessionLangMap = new HashMap<String, Map<String,String>>();
	
	private LanguageService() {}
	
	/**
	 * 单例获取
	 * @return
	 */
	public static synchronized LanguageService getInstance() {
		if(languageService == null){
			languageService = new LanguageService();
		}
		return languageService;
	}
	
	/**
	 * 
	 * 加载初始化的语言
	 */
	public void loadDefault(String lang){
		if(defaultLangMap != null){ return; }
		PhpEnvironment phpEnv = null;
		try {
			phpEnv = PhpEnvKit.getPhpEnv(); // 对象池获取对象
			/**读取内容开始**/
			Environment env = phpEnv.getEnv();
			CompileScope scope = phpEnv.getScope();
			synchronized (env) {
				env.getGlobals().clear();
				ModuleEntity moduleEntity = phpEnv.getModuleEntity(lang);
				try {
					moduleEntity.includeNoThrow(env);
				} finally {
					scope.triggerProgramShutdown(env);
					try {
						env.doFinal();
					} catch (Throwable e) {
						LogKit.error("render异常！",e);
						throw new PhpRenderException("render异常！",e);
					}
				}
			}
			defaultLangMap = new HashMap<String, String>();
			ReferenceMemory memory = (ReferenceMemory)env.getGlobals().refOfIndex("_");
			ForeachIterator newIterator = memory.getNewIterator(env);
			while (newIterator.next()) {
				defaultLangMap.put(newIterator.getStringKey(), newIterator.getValue().toString());
			}
		} catch (Throwable e) {
			LogKit.error("获取PhpEnvironment异常",e);
			throw new RenderException("获取PhpEnvironment异常",e);
		} finally {
			PhpEnvKit.release(phpEnv);
		}
	}
	
	/**
	 * 
	 * @param lang
	 */
	public void load(String lang){
		lang = MessageFormat.format(lang, SessionConfigService.get("config_language"));
		PhpEnvironment phpEnv = null;
		try {
			phpEnv = PhpEnvKit.getPhpEnv(); // 对象池获取对象
			File langFile = new File(phpEnv.getBasePath(), lang);
			String key = lang.concat(langFile.lastModified()+"");
			currentLoad.set(key);	//设置当前加载的语言文件
			Map<String, String> langMap = allLangMap.get(key);
			if(langMap != null){ return; }
			/**读取内容开始**/
			Environment env = phpEnv.getEnv();
			CompileScope scope = phpEnv.getScope();
			synchronized (env) {
				env.getGlobals().clear();
				ModuleEntity moduleEntity = phpEnv.getModuleEntity(lang);
				try {
					moduleEntity.includeNoThrow(env);
				} finally {
					scope.triggerProgramShutdown(env);
					try {
						env.doFinal();
					} catch (Throwable e) {
						LogKit.error("render异常！",e);
						throw new PhpRenderException("render异常！",e);
					}
				}
			}
			langMap = new HashMap<String, String>();
			ReferenceMemory memory = (ReferenceMemory)env.getGlobals().refOfIndex("_");
			ForeachIterator newIterator = memory.getNewIterator(env);
			while (newIterator.next()) {
				langMap.put(newIterator.getStringKey(), newIterator.getValue().toString());
			}
			/**去读内容结束**/
			allLangMap.put(key, langMap);
			
		} catch (Throwable e) {
			LogKit.error("获取PhpEnvironment异常",e);
			throw new RenderException("获取PhpEnvironment异常",e);
		} finally {
			PhpEnvKit.release(phpEnv);
		}
	}
	
	/**
	 * 获取内容返回Memory
	 * @param key
	 * @return
	 */
	public Memory get(String key){
		return MemoryUtils.valueOf(getStr(key));
	}
	
	/**
	 * 获取内容返回String
	 * @param key
	 * @return
	 */
	public String getStr(String key){
		String value = null;
		if(currentLoad.get() != null){
			value = allLangMap.get(currentLoad.get()).get(key);
		}
		if(value == null){
			value = sessionLangMap.get(SessionConfigService.get("config_language")).get(key);
		}
		if(value == null){
			value = defaultLangMap.get(key);
		}
		return value;
	}

	/**
	 * session级别默认语言
	 * @param lang
	 */
	public void loadSession(String lang) {
		String code = SessionConfigService.get("config_language");
		lang = MessageFormat.format(lang, code,SessionConfigService.get("config_language"));
		PhpEnvironment phpEnv = null;
		try {
			phpEnv = PhpEnvKit.getPhpEnv(); // 对象池获取对象
			String key = code;
			Map<String, String> langMap = sessionLangMap.get(key);
			if(langMap != null){ return; }
			/**读取内容开始**/
			Environment env = phpEnv.getEnv();
			CompileScope scope = phpEnv.getScope();
			synchronized (env) {
				env.getGlobals().clear();
				ModuleEntity moduleEntity = phpEnv.getModuleEntity(lang);
				try {
					moduleEntity.includeNoThrow(env);
				} finally {
					scope.triggerProgramShutdown(env);
					try {
						env.doFinal();
					} catch (Throwable e) {
						LogKit.error("render异常！",e);
						throw new PhpRenderException("render异常！",e);
					}
				}
			}
			langMap = new HashMap<String, String>();
			ReferenceMemory memory = (ReferenceMemory)env.getGlobals().refOfIndex("_");
			ForeachIterator newIterator = memory.getNewIterator(env);
			while (newIterator.next()) {
				langMap.put(newIterator.getStringKey(), newIterator.getValue().toString());
			}
			/**去读内容结束**/
			sessionLangMap.put(key, langMap);
			
		} catch (Throwable e) {
			LogKit.error("获取PhpEnvironment异常",e);
			throw new RenderException("获取PhpEnvironment异常",e);
		} finally {
			PhpEnvKit.release(phpEnv);
		}
	}
	
	/**
	 * 重置线程变量
	 */
	public static void reset() {
		currentLoad.set(null);
	}

}
